package com.synjones.zeuscloudweb.controller;

import cn.apiclub.captcha.Captcha;
import cn.apiclub.captcha.backgrounds.GradiatedBackgroundProducer;
import cn.apiclub.captcha.gimpy.FishEyeGimpyRenderer;
import com.synjones.zeus.model.AvailableStatus;
import com.synjones.zeus.model.CodeStr;
import com.synjones.zeus.model.web.AdminBean;
import com.synjones.zeuscloudweb.service.LoginService;
import com.synjones.zeuscloudweb.util.ccl.datastructure.impl.BaseDto;
import com.synjones.zeuscloudweb.util.ccl.util.G4Utils;
import net.sf.json.JSONObject;
import org.apache.ibatis.annotations.Param;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.imageio.ImageIO;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @author yys
 * Description: 登陆
 * @date created in 16:50 2017/12/28
 * Modified by:
 */
@Controller
@RequestMapping("/login")
public class LoginController {
    @Autowired
    @Qualifier("loginServiceImpl")
    private LoginService loginService;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    //超时时间3min
    private static int captchaExpires = 3 * 60;
    //验证码宽
    private static int captchaW = 200;
    //验证码高
    private static int captchaH = 50;
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * @author yys
     * Description: 登陆页跳转
     * @date 16:53 2017/12/28
     */
    @RequestMapping(value = "/loginInfo", method = RequestMethod.GET)
    public String login() {
        return "login2";
    }

    /**
     * @author yys
     * Description: 用户登陆
     * @date 16:54 2017/12/28
     */
    @RequestMapping(value = "/loginUser", method = RequestMethod.POST)
    public void loginUser(String username, String password, String captchaCodeKey, String captchaCodeValue,
                          HttpSession session, HttpServletResponse response) throws IOException {
        PrintWriter pw = response.getWriter();
        String code = redisTemplate.opsForValue().get(captchaCodeKey);
        BaseDto jsonDto = new BaseDto();
        if (!captchaCodeValue.equals(code)) {
            jsonDto.put("success", new Boolean(false));
            jsonDto.put("msg", "验证码输入错误,请重新输入!");
            jsonDto.put("errorType", "1");
            pw.write(JSONObject.fromObject(jsonDto).toString());
            pw.close();
            return;
        }
        UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(username, G4Utils.encryptBasedDes(password));
        Subject subject = SecurityUtils.getSubject();
        try {
            //完成登录
            subject.login(usernamePasswordToken);
            AdminBean admin = (AdminBean) subject.getPrincipal();
            if (AvailableStatus._1.code().equals(admin.getAvailable())) {
                session.setAttribute(String.valueOf(admin.getUserId()), admin);
                session.setAttribute(CodeStr.SESSION_KEY_USERID, admin.getUserId());
                logger.debug("账户" + admin.getUserName() + "登陆系统!");
                jsonDto.put("success", new Boolean(true));
                jsonDto.put("username", admin.getUserName());
                jsonDto.put("userId", admin.getUserId());
            } else {
                jsonDto.put("success", new Boolean(false));
                jsonDto.put("msg", "该用户账号已被禁用，无法登录");
                jsonDto.put("errorType", "1");
            }
            pw.write(JSONObject.fromObject(jsonDto).toString());
            pw.close();
        } catch (Exception e) {
            logger.error("", e);
            jsonDto.put("success", new Boolean(false));
            jsonDto.put("msg", "登陆失败,请重新输入!");
            jsonDto.put("errorType", "1");
            pw.write(JSONObject.fromObject(jsonDto).toString());
            pw.close();
        }
    }

    /**
     * @author yys
     * Description: 首页跳转
     * @date 16:53 2017/12/28
     */
    @RequestMapping(value = "/indexInfo", method = RequestMethod.GET)
    public String indexInfo(@Param("userId") String userId, HttpSession session, Model model) {
        AdminBean adminBean = (AdminBean) session.getAttribute(userId);
        String roleName = loginService.findRoleNameByUserId(String.valueOf(adminBean.getUserId()));
        model.addAttribute("adminVO", adminBean);
        model.addAttribute("roleName", roleName);
        if (G4Utils.isEmpty(roleName)) {
            return "mistake";
        } else {
            return "index";
        }
    }

    /**
     * 欢迎页跳转
     *
     * @param
     * @return throws
     * @author yys
     * Description:  欢迎页跳转
     * @date 15:20 2018-01-12
     */
    @RequestMapping(value = "/welcomeInfo", method = RequestMethod.GET)
    public String welcomeInfo() {
        return "welcome";
    }


    @RequestMapping(value = "/loginOut", method = RequestMethod.POST)
    public void loginOut(@Param("userId") String userId, HttpServletResponse response,
                         HttpSession session) throws IOException {
        PrintWriter pw = response.getWriter();
        BaseDto jsonDto = new BaseDto();
        try {
            //完成退出
            Subject subject = SecurityUtils.getSubject();
            AdminBean adminBean = (AdminBean) session.getAttribute(userId);
            String userName = adminBean.getUserName();
            subject.logout();
//            session.removeAttribute(userId);
            logger.debug("账户" + userName + "退出系统!");
            jsonDto.put("success", new Boolean(true));
            jsonDto.put("msg", "退出成功");
            jsonDto.put("data", null);
        } catch (Exception e) {
            jsonDto.put("success", new Boolean(false));
            jsonDto.put("msg", "退出失败,请重试!");
            jsonDto.put("data", null);
        } finally {
            pw.write(JSONObject.fromObject(jsonDto).toString());
            pw.close();
        }
    }

    @RequestMapping(value = "/mistake", method = RequestMethod.GET)
    public String mistake() {
        return "mistake";
    }

    /**
     * @author yys
     * Description: 生成验证码
     * @date 16:54 2017/12/28
     */
    @RequestMapping(value = "/getcaptcha", method = RequestMethod.GET, produces = MediaType.IMAGE_PNG_VALUE)
    public @ResponseBody
    byte[] getCaptcha(HttpServletResponse response, HttpServletRequest request) {
        String uuid = UUID.randomUUID().toString();
        Captcha captcha = new Captcha.Builder(captchaW, captchaH)
                .addText().addBackground(new GradiatedBackgroundProducer())
                .gimp(new FishEyeGimpyRenderer())
                .build();
        //将验证码以<key,value>形式缓存到redis
        redisTemplate.opsForValue().set(uuid, captcha.getAnswer(), captchaExpires, TimeUnit.SECONDS);
        //将验证码key，及验证码的图片返回
        Cookie cookie = new Cookie("captchaCodeKey", uuid);
        response.addCookie(cookie);
//        Cookie[] cookies = request.getCookies();
//        for (Cookie c : cookies) {
//            System.out.println(c.getName() + "--->" + c.getValue());
//        }
        ByteArrayOutputStream bao = new ByteArrayOutputStream();
        try {
            ImageIO.write(captcha.getImage(), "png", bao);
            return bao.toByteArray();
        } catch (IOException e) {
            return null;
        }
    }
}
